//
//  TodayDetailCalendarViewModel.swift
//  MoyoungHome
//
//  Created by 易先生 on 2022/9/21.
//

import UIKit
import HandyJSON
import RxCocoa
import MYModule
import Differentiator
import RxDataSources
import SwiftDate

public enum CalendarShowType {
    
    case step24h
    case heart24h
    case spo24h
    case sleep24h
    case hrv24h
    
}

public extension CalendarShowType {
    
    var SQLModelclass: MYSQLiteTableiabe.Type {
        
        switch self {
        case .step24h:
            return ActivityModel.self
        case .heart24h:
            return HeartRateModel.self
        case .spo24h:
            return BloodOxygenModel.self
        case .sleep24h:
            return SleepModel.self
        case .hrv24h:
            return HRVModel.self
        }
        
    }
}


open class CalendarViewModel: NSObject {

	public var showType: CalendarShowType = .heart24h
        
	public var calendarSections: [CalendarSectionModel] = []
    
    /// 被点击的
    public var selectedItem: CalendarModel?
    

	public init(showType: CalendarShowType) {
		super.init()
		self.showType = showType
	}

	public func getCalendarDatas() {
        
		var months = [String]()
		var datas = [[CalendarModel]]()
        let nowYear = Date().year
		let nowMonth = Date().month
		let firstDate = getFirstDataDate()
		var numberMonths = 0
		while 0 < nowMonth {

            guard let calculatedDate = Calendar.current.date(byAdding: .month, value: numberMonths, to: firstDate) else {
                continue
            }
			
            
            let days =
            getYearWithMonthQueryDays(date: calculatedDate)
            let month = calculatedDate.toString(.custom("yyyy-MM"))
            months.append(month)
			datas.append(days)

			numberMonths += 1
            if calculatedDate.year == nowYear && calculatedDate.month == nowMonth {
				break
			}
		}

		calendarSections.removeAll()
		for (i, monthString) in months.enumerated() {
			let monthComp = monthString.components(separatedBy: "-")
			let year = Int(monthComp[0])
			let month = Int(monthComp[1])
            
            var items = datas[i]
			
			for (j, item) in items.enumerated() {
				let strokeColor = getDayStrokeColorWithType()
                item.bgColor = strokeColor?.withAlphaComponent(0.2)
				item.fillColor = strokeColor

				item.year = year!
				item.month = month!
				item.day = j + 1
				
//				calendarItems.append(item!)
            }
            
            // 插入空白cell
            let firstDate = Date(year: year!, month: month!, day: 1, hour: 0, minute: 0)
            let firstWeek = firstDate.weekday
            
            // 刚好是周日开始就不需要插入空白
            if firstWeek > 1 {
                
                for _ in 1 ..< firstWeek {
                    items.insert(CalendarModel.empty(type: .past), at: 0)
                }
            }
            
            guard let aMonth = monthString.toDate("yyyy-MM")?.date else {
                continue
            }
            
            let monthName = aMonth.monthName(.default)
            let seactionModel = CalendarSectionModel(month: monthName, items: items)
			calendarSections.append(seactionModel)
            
          
            
		}
	}

	private func getFirstDataDate() -> Date {
        
        var fristDateModel: MYSQLiteTableiabe?
        
		switch showType {
		case .step24h:
            if let model = ActivityModel.first() {
                fristDateModel = model
            }
            
		case .heart24h:
            
            if let model = HeartRateModel.first() {
                fristDateModel = model
            }
            
		case .spo24h:
            
            if let model = BloodOxygenModel.first() {
                fristDateModel = model
            }
            
		case .sleep24h:
            
            if let model = SleepModel.first() {
                fristDateModel = model
            }
			
        case .hrv24h:
            if let model = HRVModel.first() {
                fristDateModel = model
            }
        }
        return fristDateModel?.date ?? Date()
	}

    private func getYearWithMonthQueryDays(date: Date) -> [CalendarModel] {
		var days: [CalendarModel?] = []
        let firstDate = Date(year: date.year, month: date.month, day: 1, hour: 0, minute: 0)
        let lastDayDate = Date(year: date.year, month: date.month, day: date.monthDays, hour: 0, minute: 0)
        let toDayTime = Date().timeIntervalSince1970
        
		switch showType {
		case .step24h:
           let month = ActivityModel.monthSortData(date: lastDayDate)
            days = month.enumerated().map {
                
                let dayTime = (firstDate + $0.days).timeIntervalSince1970
                if dayTime > toDayTime {
                    return CalendarModel.empty(type: .future)
                }
                 
                 if $1.isEmpty {
                     
                  return CalendarModel.empty(type: .empty)
                 }
                let model = $1.first
                if model?.isEmpty == true {
                    return CalendarModel.empty(type: .empty)
                }
                
                let itemModel = CalendarModel()
                itemModel.type = .real
                itemModel.sqliteModel = model
                if model?.date.isToday == true {
                    itemModel.isSelected = true
                    selectedItem = itemModel
                }
                return itemModel
             }
            
		case .heart24h:
           let month = HeartRateModel.monthSortData(date: lastDayDate)
            days = month.enumerated().map {
                
                let dayTime = (firstDate + $0.days).timeIntervalSince1970
                if dayTime > toDayTime {
                    return CalendarModel.empty(type: .future)
                }
                 
                 if $1.isEmpty {
                     
                  return CalendarModel.empty(type: .empty)
                 }
                let model = $1.first
                if model?.isEmpty == true {
                    return CalendarModel.empty(type: .empty)
                }
                let itemModel = CalendarModel()
                itemModel.sqliteModel = model
                itemModel.type = .real
                if model?.date.isToday == true {
                    itemModel.isSelected = true
                    selectedItem = itemModel
                }
                return itemModel
                
             }
            
		case .spo24h:
            
            let month = HRVModel.monthSortData(date: lastDayDate)
             days = month.enumerated().map {
                 
                 let dayTime = (firstDate + $0.days).timeIntervalSince1970
                 if dayTime > toDayTime {
                     return CalendarModel.empty(type: .future)
                 }
                  
                  if $1.isEmpty {
                      
                   return CalendarModel.empty(type: .empty)
                  }
                 let model = $1.first
                 if model?.isEmpty == true {
                     return CalendarModel.empty(type: .empty)
                 }
                 let itemModel = CalendarModel()
                 itemModel.sqliteModel = model
                 itemModel.type = .real
                 if model?.date.isToday == true {
                     itemModel.isSelected = true
                     selectedItem = itemModel
                 }
                 return itemModel
                 
              }
            
            break
   
		case .sleep24h:
            let month = SleepModel.monthSortData(date: lastDayDate)
            days = month.enumerated().map {
                
                let dayTime = (firstDate + $0.days).timeIntervalSince1970
                if dayTime > toDayTime {
                    
                    return CalendarModel.empty(type: .future)
                }
                
                 if $1.isEmpty {
                     
                  return CalendarModel.empty(type: .empty)
                 }
                
                let model = $1.first
                if model?.isEmpty == true {
                    return CalendarModel.empty(type: .empty)
                }
                let itemModel = CalendarModel()
                itemModel.sqliteModel = model
                itemModel.type = .real
                if model?.date.isToday == true {
                    itemModel.isSelected = true
                    selectedItem = itemModel
                }
                return itemModel
             }
            
        case .hrv24h:
            let month = HRVModel.monthSortData(date: lastDayDate)
             days = month.enumerated().map {
                 
                 let dayTime = (firstDate + $0.days).timeIntervalSince1970
                 if dayTime > toDayTime {
                     return CalendarModel.empty(type: .future)
                 }
                  
                  if $1.isEmpty {
                      
                   return CalendarModel.empty(type: .empty)
                  }
                 let model = $1.first
                 if model?.isEmpty == true {
                     return CalendarModel.empty(type: .empty)
                 }
                 let itemModel = CalendarModel()
                 itemModel.sqliteModel = model
                 itemModel.type = .real
                 if model?.date.isToday == true {
                     itemModel.isSelected = true
                     selectedItem = itemModel
                 }
                 return itemModel
                 
              }
        }
        
        
       let models: [CalendarModel] = days.map {
            
            guard let model = $0 else {
                
                return CalendarModel.empty(type: .empty)
            
            }
            return model
        }
        
        return models
	}

	private func getDayStrokeColorWithType() -> UIColor? {
        var strokeColor: UIColor? = UIColor.black
		switch showType {
		case .step24h:
            strokeColor = UIColor.Step.theme
		case .heart24h:
            strokeColor = UIColor.HeartRate.theme
		case .spo24h:
            strokeColor = UIColor.BloodOxygen.theme
		case .sleep24h:
            strokeColor = UIColor.Sleep.theme
        case .hrv24h:
            strokeColor = UIColor.HRV.theme
        }
		return strokeColor
	}

	public func getWeekCalendarTextColor() -> UIColor {
        
		let textColor = UIColor.assist_222222
		return textColor
	}

	public func numberOfSections() -> Int {
		return calendarSections.count
	}

	public func numberOfItemsInSection(section: Int) -> Int {
		return calendarSections[section].items.count
	}

	

	public func cellForItemAtCellModel(indexPath: IndexPath) -> CalendarModel {
		return calendarSections[indexPath.section].items[indexPath.row]
	}

	private lazy var dateFormat: DateFormatter = {
		let dateFormat = DateFormatter()
		dateFormat.locale = myLocal
		dateFormat.dateFormat = "yyyy-MM-dd"
		dateFormat.calendar = Calendar.init(identifier: .gregorian)
		return dateFormat
	}()
}
